/**
 * Chart.js封装服务
 * 提供统一的图表创建、更新、销毁方法
 */
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  BarElement,
  ArcElement,
  Title,
  Tooltip,
  Legend,
  Filler
} from 'chart.js'

// 注册Chart.js组件
ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  BarElement,
  ArcElement,
  Title,
  Tooltip,
  Legend,
  Filler
)

/**
 * 颜色配置
 */
export const chartColors = {
  primary: 'rgba(102, 126, 234, 0.8)',
  primaryLight: 'rgba(102, 126, 234, 0.2)',
  secondary: 'rgba(118, 75, 162, 0.8)',
  secondaryLight: 'rgba(118, 75, 162, 0.2)',
  success: 'rgba(67, 233, 123, 0.8)',
  successLight: 'rgba(67, 233, 123, 0.2)',
  warning: 'rgba(240, 147, 251, 0.8)',
  warningLight: 'rgba(240, 147, 251, 0.2)',
  danger: 'rgba(245, 87, 108, 0.8)',
  dangerLight: 'rgba(245, 87, 108, 0.2)',
  info: 'rgba(79, 172, 254, 0.8)',
  infoLight: 'rgba(79, 172, 254, 0.2)',
  
  // 渐变色方案
  gradients: [
    'rgba(102, 126, 234, 0.8)',
    'rgba(118, 75, 162, 0.8)',
    'rgba(240, 147, 251, 0.8)',
    'rgba(245, 87, 108, 0.8)',
    'rgba(79, 172, 254, 0.8)',
    'rgba(0, 242, 254, 0.8)',
    'rgba(67, 233, 123, 0.8)',
    'rgba(56, 249, 215, 0.8)'
  ]
}

/**
 * 通用图表配置
 */
export const commonChartOptions = {
  responsive: true,
  maintainAspectRatio: false,
  plugins: {
    legend: {
      display: true,
      position: 'top',
      labels: {
        color: '#606266',
        font: {
          size: 12
        },
        padding: 15,
        usePointStyle: true
      }
    },
    tooltip: {
      enabled: true,
      mode: 'index',
      intersect: false,
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      titleColor: '#fff',
      bodyColor: '#fff',
      borderColor: 'rgba(255, 255, 255, 0.2)',
      borderWidth: 1,
      padding: 10,
      displayColors: true
    }
  },
  interaction: {
    mode: 'nearest',
    axis: 'x',
    intersect: false
  }
}

/**
 * Chart.js服务类
 */
class ChartService {
  constructor() {
    this.charts = new Map() // 存储图表实例
  }

  /**
   * 创建折线图
   * @param {HTMLCanvasElement} canvas - canvas元素
   * @param {Object} data - 图表数据
   * @param {Object} options - 自定义配置
   * @returns {Chart} 图表实例
   */
  createLineChart(canvas, data, options = {}) {
    const chartId = this.generateChartId(canvas)
    
    // 销毁旧图表
    this.destroyChart(chartId)
    
    const config = {
      type: 'line',
      data: data,
      options: {
        ...commonChartOptions,
        ...options,
        scales: {
          x: {
            grid: {
              display: false
            },
            ticks: {
              color: '#909399'
            }
          },
          y: {
            beginAtZero: true,
            grid: {
              color: 'rgba(0, 0, 0, 0.05)'
            },
            ticks: {
              color: '#909399'
            }
          }
        }
      }
    }
    
    const chart = new ChartJS(canvas, config)
    this.charts.set(chartId, chart)
    
    return chart
  }

  /**
   * 创建柱状图
   * @param {HTMLCanvasElement} canvas - canvas元素
   * @param {Object} data - 图表数据
   * @param {Object} options - 自定义配置
   * @returns {Chart} 图表实例
   */
  createBarChart(canvas, data, options = {}) {
    const chartId = this.generateChartId(canvas)
    
    // 销毁旧图表
    this.destroyChart(chartId)
    
    const config = {
      type: 'bar',
      data: data,
      options: {
        ...commonChartOptions,
        ...options,
        scales: {
          x: {
            grid: {
              display: false
            },
            ticks: {
              color: '#909399'
            }
          },
          y: {
            beginAtZero: true,
            grid: {
              color: 'rgba(0, 0, 0, 0.05)'
            },
            ticks: {
              color: '#909399'
            }
          }
        }
      }
    }
    
    const chart = new ChartJS(canvas, config)
    this.charts.set(chartId, chart)
    
    return chart
  }

  /**
   * 创建饼图
   * @param {HTMLCanvasElement} canvas - canvas元素
   * @param {Object} data - 图表数据
   * @param {Object} options - 自定义配置
   * @returns {Chart} 图表实例
   */
  createPieChart(canvas, data, options = {}) {
    const chartId = this.generateChartId(canvas)
    
    // 销毁旧图表
    this.destroyChart(chartId)
    
    const config = {
      type: 'pie',
      data: data,
      options: {
        ...commonChartOptions,
        ...options
      }
    }
    
    const chart = new ChartJS(canvas, config)
    this.charts.set(chartId, chart)
    
    return chart
  }

  /**
   * 创建环形图
   * @param {HTMLCanvasElement} canvas - canvas元素
   * @param {Object} data - 图表数据
   * @param {Object} options - 自定义配置
   * @returns {Chart} 图表实例
   */
  createDoughnutChart(canvas, data, options = {}) {
    const chartId = this.generateChartId(canvas)
    
    // 销毁旧图表
    this.destroyChart(chartId)
    
    const config = {
      type: 'doughnut',
      data: data,
      options: {
        ...commonChartOptions,
        ...options,
        cutout: '70%' // 环形图内圈大小
      }
    }
    
    const chart = new ChartJS(canvas, config)
    this.charts.set(chartId, chart)
    
    return chart
  }

  /**
   * 创建混合图表（柱状+折线）
   * @param {HTMLCanvasElement} canvas - canvas元素
   * @param {Object} data - 图表数据
   * @param {Object} options - 自定义配置
   * @returns {Chart} 图表实例
   */
  createMixedChart(canvas, data, options = {}) {
    const chartId = this.generateChartId(canvas)
    
    // 销毁旧图表
    this.destroyChart(chartId)
    
    const config = {
      type: 'bar',
      data: data,
      options: {
        ...commonChartOptions,
        ...options,
        scales: {
          x: {
            grid: {
              display: false
            },
            ticks: {
              color: '#909399'
            }
          },
          y: {
            beginAtZero: true,
            grid: {
              color: 'rgba(0, 0, 0, 0.05)'
            },
            ticks: {
              color: '#909399'
            }
          }
        }
      }
    }
    
    const chart = new ChartJS(canvas, config)
    this.charts.set(chartId, chart)
    
    return chart
  }

  /**
   * 更新图表数据
   * @param {string|Chart} chartOrId - 图表实例或ID
   * @param {Object} newData - 新数据
   */
  updateChart(chartOrId, newData) {
    const chart = typeof chartOrId === 'string' 
      ? this.charts.get(chartOrId) 
      : chartOrId
    
    if (!chart) {
      console.warn('图表实例不存在')
      return
    }
    
    // 更新数据
    if (newData.labels) {
      chart.data.labels = newData.labels
    }
    
    if (newData.datasets) {
      chart.data.datasets = newData.datasets
    }
    
    // 更新图表
    chart.update('active')
  }

  /**
   * 销毁图表
   * @param {string|Chart} chartOrId - 图表实例或ID
   */
  destroyChart(chartOrId) {
    const chartId = typeof chartOrId === 'string' ? chartOrId : this.generateChartId(chartOrId?.canvas)
    const chart = this.charts.get(chartId)
    
    if (chart) {
      chart.destroy()
      this.charts.delete(chartId)
    }
  }

  /**
   * 销毁所有图表
   */
  destroyAllCharts() {
    this.charts.forEach(chart => {
      chart.destroy()
    })
    this.charts.clear()
  }

  /**
   * 获取图表实例
   * @param {string} chartId - 图表ID
   * @returns {Chart|null} 图表实例
   */
  getChart(chartId) {
    return this.charts.get(chartId) || null
  }

  /**
   * 生成图表ID
   * @param {HTMLCanvasElement} canvas - canvas元素
   * @returns {string} 图表ID
   */
  generateChartId(canvas) {
    if (!canvas) return `chart_${Date.now()}_${Math.random()}`
    
    // 使用canvas的id或生成唯一ID
    if (canvas.id) {
      return canvas.id
    }
    
    const id = `chart_${Date.now()}_${Math.random()}`
    canvas.id = id
    return id
  }

  /**
   * 导出图表为图片
   * @param {string|Chart} chartOrId - 图表实例或ID
   * @param {string} filename - 文件名
   */
  exportChartAsImage(chartOrId, filename = 'chart.png') {
    const chart = typeof chartOrId === 'string' 
      ? this.charts.get(chartOrId) 
      : chartOrId
    
    if (!chart) {
      console.warn('图表实例不存在')
      return
    }
    
    const url = chart.toBase64Image()
    const link = document.createElement('a')
    link.download = filename
    link.href = url
    link.click()
  }

  /**
   * 准备图表数据格式
   * @param {Array} labels - 标签数组
   * @param {Array} datasets - 数据集数组
   * @returns {Object} Chart.js数据格式
   */
  prepareChartData(labels, datasets) {
    return {
      labels,
      datasets: datasets.map((dataset, index) => ({
        label: dataset.label || `数据集 ${index + 1}`,
        data: dataset.data || [],
        backgroundColor: dataset.backgroundColor || chartColors.gradients[index % chartColors.gradients.length],
        borderColor: dataset.borderColor || chartColors.gradients[index % chartColors.gradients.length].replace('0.8', '1'),
        borderWidth: dataset.borderWidth || 2,
        tension: dataset.tension || 0.4,
        fill: dataset.fill !== undefined ? dataset.fill : false,
        ...dataset
      }))
    }
  }
}

// 创建单例实例
const chartService = new ChartService()

// 导出服务实例和工具
export default chartService
export { ChartJS, chartService }

